home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-25 | 19.5 KB | 705 lines | [TEXT/MPS ] |
- {Copyright © 1989 by Apple Computer, Inc. All rights reserved.}
-
-
-
- CONST
- kIconHBits = 32; { Number of horizontal bits in a bitmap.}
- kIconVBits = 32; { Number of vertical bits in a bitmap. }
-
- kIconSizeInBytes = kIconHBits * kIconVBits DIV 8; { Number of bytes in an bitmap. }
- kIconSizeInLongs = kIconSizeInBytes DIV 4; { Number of long words in a bitmap. }
- kMaxLong = kIconSizeInLongs - 1; { Max. addressable long word in bitmap. }
-
-
- { Resource identifiers }
-
- kSeedIconId = 1000; { Id of the seed icon resource. }
-
- kIconWindowId = 1000; { Id of the icon window 'view' resource.}
- kIconViewId = 1001; { Id of the TIconView resource. }
-
-
- { Constants for TIconView }
-
- kDefaultMagnification = 7; { Default icon magnification. }
- kBorder = 5; { Border in which to inset drawing. }
-
- { Command Numbers }
-
- cZoomIn = 1000; { Zoom In menu command. }
- cZoomOut = 1001; { Zoom Out menu command. }
- cInvert = 1002; { Invert menu command. }
- cDrawCommand = 1003; { Icon drawing-a mouse tracking command }
-
-
-
-
- TYPE
- LongArrayHdl = ^LongArrayPtr;
- LongArrayPtr = ^LongArray;
- LongArray = ARRAY [0..kMaxLong] OF LONGINT;
-
-
-
- {-------------------------------------------------------------------------------------------}
- {--------------------------------TIconApplication methods-----------------------------------}
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconApplication.IIconApplication(iconFileType: OSType);
-
- VAR anIconView : TIconView;
-
- BEGIN
- IApplication(iconFileType);
-
- if gCreateWithTemplates then begin { Make sure the linker doesn't strip out view code. }
- New(anIconView);
- end;
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- FUNCTION TIconApplication.DoMakeDocument(itsCmdNumber: CmdNumber): TDocument; OVERRIDE;
-
- VAR
- anIconDocument: TIconDocument;
-
- BEGIN
- New(anIconDocument); { Create a TIconDocument object. }
- FailNIL(anIconDocument); { Make sure we were successful. }
- anIconDocument.IIconDocument; { Initialize it. }
-
- DoMakeDocument := anIconDocument; { Return a reference to the document. }
- END;
-
-
-
-
- {-------------------------------------------------------------------------------------------}
- {----------------------------------TIconDocument methods------------------------------------}
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconDocument.IIconDocument;
-
- VAR anIconBitMap : TIconBitMap;
-
- BEGIN
- fIconBitMap := NIL; { Set this to NIL so that if IDocument }
- { fails, TIconDocument.Free works okay. }
-
- IDocument(kFileType, { This document's file type. }
- kSignature, { This document's creator. }
- kUsesDataFork, { This document does use the data fork }
- NOT kUsesRsrcFork, { …but doesn't use the resource fork. }
- NOT kDataOpen, { We don't want the data fork kept open }
- NOT kRsrcOpen); { …nor the resource fork. }
-
- New(anIconBitMap); { Allocate a new icon bitmap. }
- FailNil(anIconBitMap); { Fail if we can't allocate the handle. }
- anIconBitMap.IIconBitMap; { Initialize it. }
-
- fIconBitMap := anIconBitMap; { Store a reference to it in a field. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconDocument.DoInitialState; OVERRIDE;
- { This method is called to set the document's data to the "new" state, as when the user }
- { chooses to open a new document instead of an existing one. We set the value of the }
- { document's icon bit map to that of a "seed" icon in our resource file. That way we }
- { can the document's initial state simply by changing the "seed" icon resource. }
-
- VAR
- seedIcon: Handle;
-
- BEGIN
- seedIcon := GetIcon(kSeedIconId); { Get the seed icon resource. }
- FailNilResource(seedIcon);
- fIconBitMap.SetIconBitMap(seedIcon)
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconDocument.Free; OVERRIDE;
-
- BEGIN
- FreeIfObject(fIconBitMap); { Dispose of the icon object if non-Nil.}
-
- INHERITED Free;
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconDocument.DoMakeViews (forPrinting: BOOLEAN); OVERRIDE;
-
- VAR
- aWindow: TWindow;
-
- BEGIN
- aWindow := NewTemplateWindow(kIconWindowId, SELF); { Create the view hierarchy }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconDocument.RedrawViews;
-
- PROCEDURE InvalidateView (aView: TView);
-
- BEGIN
- aView.ForceRedraw; { Cause the view to be redrawn. }
- END;
-
- BEGIN
- ForAllViewsDo(InvalidateView); { Call InvalidateView on each of }
- { …the document's views. }
- END;
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconDocument.DoSetupMenus; OVERRIDE;
-
- BEGIN
- INHERITED DoSetupMenus; { Set up inherited menus. }
-
- Enable(cInvert, TRUE); { The icon can always be inverted. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- FUNCTION TIconDocument.DoMenuCommand (aCmdNumber: CmdNumber): TCommand; OVERRIDE;
-
- VAR
- anInvertCommand: TInvertCommand;
-
- BEGIN
- CASE aCmdNumber OF
- cInvert:
- BEGIN
- New(anInvertCommand);
- FailNIL(anInvertCommand);
- anInvertCommand.IInvertCommand(SELF);
- DoMenuCommand := anInvertCommand;
- END;
- OTHERWISE
- DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
- END;
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconDocument.InvertIcon;
-
- BEGIN
- fIconBitMap.Invert; { Invert the bits of the icon. }
- RedrawViews; { Make sure all views get redrawn. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconDocument.Fields (PROCEDURE DoToField (fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TIconDocument', NIL, bClass);
- DoToField('fIconBitMap', @fIconBitMap, bObject);
-
- INHERITED Fields(DoToField);
- END;
-
-
- {-------------------------------------------------------------------------------------------}
- {------------------------------------TIconView methods--------------------------------------}
- {-------------------------------------------------------------------------------------------}
-
-
- PROCEDURE TIconView.IRes (itsDocument: TDocument; itsSuperView: TView; VAR itsParams: Ptr);
-
- BEGIN
- INHERITED IRes(itsDocument, itsSuperView, itsParams);
-
- fMagnification := kDefaultMagnification;
- fIconDocument := TIconDocument(itsDocument);
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconView.CalcMinSize (VAR minSize: VPoint); OVERRIDE;
-
- BEGIN
- minSize.h := kIconHBits * fMagnification + kBorder + kBorder;
- minSize.v := kIconVBits * fMagnification + kBorder + kBorder;
- END;
-
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconView.Draw (area: Rect); OVERRIDE;
-
- VAR
- drawingRect: Rect;
-
- BEGIN
- SetRect(drawingRect, kBorder, kBorder,
- kBorder + (kIconHBits * fMagnification),
- kBorder + (kIconVBits * fMagnification));
-
- fIconDocument.fIconBitMap.Draw(drawingRect);
- END;
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconView.DrawBit (theBit: Point; turnBitOn: BOOLEAN);
-
- VAR
- theRect: Rect;
- thePattern: Pattern;
-
- BEGIN
- SetRect(theRect, { Setup the bit's rect the in edit view.}
- kBorder + theBit.h * fMagnification,
- kBorder + theBit.v * fMagnification,
- kBorder + (theBit.h + 1) * fMagnification,
- kBorder + (theBit.v + 1) * fMagnification);
-
- IF turnBitOn THEN { Decide which pattern to use. }
- thePattern := black
- ELSE
- thePattern := white;
- FillRect(theRect, thePattern); { Show the bit in the edit view. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconView.DoSetupMenus; OVERRIDE;
-
- BEGIN
- INHERITED DoSetupMenus; { Set up inherited menus. }
-
- Enable(cZoomIn, TRUE); { Can always zoom in. }
- Enable(cZoomOut, fMagnification > 1); { Can zoom out if not at smallest size. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- FUNCTION TIconView.DoMenuCommand (aCmdNumber: CmdNumber): TCommand; OVERRIDE;
-
- BEGIN
- DoMenuCommand := gNoChanges; { Initialize result of DoMenuCommand. }
-
- CASE aCmdNumber OF { Decide if this command is ours… }
-
- cZoomIn:
- SetMagnification(fMagnification + 2); { Increase size of each bit by 2 pixels.}
-
- cZoomOut:
- SetMagnification(fMagnification - 2); { Decrease size of each bit by 2 pixels.}
-
- OTHERWISE { Otherwise, let someone else handle it.}
- DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
- END;
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconView.SetMagnification (magnification: INTEGER);
-
- BEGIN
- fMagnification := Max(1, magnification); { Set the new magnification. }
- AdjustSize; { Magnification affects the view's size.}
- ForceRedraw; { Force the view to be entirely redrawn.}
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- FUNCTION TIconView.DoMouseCommand (VAR theMouse: Point; VAR info: EventInfo;
- VAR hysteresis: Point): TCommand; OVERRIDE;
-
- VAR
- iconBit: Point;
- aDrawCommand: TDrawCommand;
-
- BEGIN
- IF PointToBit(theMouse, iconBit) THEN BEGIN { If point is within the icon }
- New(aDrawCommand); { …then make a drawing command. }
- FailNIL(aDrawCommand);
- aDrawCommand.IDrawCommand(SELF);
- DoMouseCommand := aDrawCommand;
- END ELSE
- DoMouseCommand := gNoChanges; { …else take no action. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- FUNCTION TIconView.PointToBit (thePoint: Point; VAR iconBit: Point): BOOLEAN;
- { Converts the given mouse point to an icon bit. }
-
- BEGIN
- thePoint.h := thePoint.h - kBorder; { Account for border in the edit view. }
- thePoint.v := thePoint.v - kBorder;
-
- { Is the mouse is within the edit view's icon… }
- IF (thePoint.h >= 0) & (thePoint.h < kIconHBits * fMagnification) &
- (thePoint.v >= 0) & (thePoint.v < kIconVBits * fMagnification) THEN
-
- BEGIN
- iconBit.h := thePoint.h DIV fMagnification; { Convert from edit view point }
- iconBit.v := thePoint.v DIV fMagnification; { …to icon bit. }
- PointToBit := TRUE;
- END
-
- ELSE
-
- PointToBit := FALSE; { Point is not within the icon. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
- PROCEDURE TIconView.Fields (PROCEDURE DoToField (fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TIconView', NIL, bClass);
- DoToField('fIconDocument', @fIconDocument, bObject);
- DoToField('fMagnification', @fMagnification, bInteger);
-
- INHERITED Fields(DoToFIeld);
- END;
-
-
-
-
-
- {-------------------------------------------------------------------------------------------}
- {----------------------------------TInvertCommand methods-----------------------------------}
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TInvertCommand.IInvertCommand (itsIconDocument: TIconDocument);
-
- BEGIN
- ICommand(cInvert, itsIconDocument, { Initialize the inherited data… }
- NIL, NIL); { …no view or scroller to track. }
-
- fIconDocument := itsIconDocument; { Save a reference to the icon document.}
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TInvertCommand.DoIt; OVERRIDE;
-
- BEGIN
- fIconDocument.InvertIcon; { Invert the document's icon bitmap. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TInvertCommand.UndoIt; OVERRIDE;
-
- BEGIN
- fIconDocument.InvertIcon; { Uninvert the document's icon bitmap. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TInvertCommand.RedoIt; OVERRIDE;
-
- BEGIN
- fIconDocument.InvertIcon; { Reinvert the document's icon bitmap. }
- END;
-
-
-
-
- {-------------------------------------------------------------------------------------------}
- {-----------------------------------TDrawCommand methods------------------------------------}
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TDrawCommand.IDrawCommand (itsIconView: TIconView);
-
- BEGIN
- ICommand(cDrawCommand, { Initialize the command… }
- itsIconView.fIconDocument, { Associate it with a document. }
- itsIconView, { Associate it with a view. }
- itsIconView.GetScroller(TRUE)); { Associate it with a scroller }
- fConstrainsMouse := TRUE; { Want TrackConstrain called. }
- fCanUndo := FALSE; { Can’t undo drawing yet... }
-
- fIconView := itsIconView; { Set some convenience fields… }
- fIconDocument := itsIconView.fIconDocument;
- fIconBitMap := fIconDocument.fIconBitMap; { Get reference to icon being drawn. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TDrawCommand.TrackConstrain(anchorPoint, previousPoint: VPoint;
- VAR nextPoint: VPoint); OVERRIDE;
-
- BEGIN
- nextPoint.h := Max(Min(nextPoint.h, fIconView.fSize.h - kBorder - 1), kBorder);
- nextPoint.v := Max(Min(nextPoint.v, fIconView.fSize.v - kBorder - 1), kBorder);
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TDrawCommand.TrackFeedback(anchorPoint, nextPoint: VPoint;
- turnItOn, mouseDidMove: BOOLEAN); OVERRIDE;
-
- BEGIN
- { Overridden to avoid standard feedback. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- FUNCTION TDrawCommand.TrackMouse(aTrackPhase: TrackPhase;
- VAR anchorPoint, previousPoint, nextPoint: VPoint;
- mouseDidMove: BOOLEAN): TCommand;
-
- VAR
- mousePoint,
- iconBit: Point;
- dontCare: BOOLEAN;
-
- BEGIN
- IF mouseDidMove THEN BEGIN { If mouse moved since last time… }
-
- { Convert nextPoint, which is in view coordinates (long integers) to mousePoint, }
- { the same location expressed in QuickDraw coordinates (integers). }
- mousePoint := fIconView.ViewToQDPt(nextPoint);
-
- { Convert mousePoint (the point on the screen) to a bit location in the icon… }
- dontCare := fIconView.PointToBit(mousePoint, iconBit);
-
- { If this is the first time TrackMouse is called, decide whether to turn bits on. }
- IF aTrackPhase = TrackPress THEN BEGIN
- fTurnBitsOn := NOT fIconBitMap.GetBit(iconBit);
- END;
-
- fIconBitMap.SetBit(iconBit, fTurnBitsOn); { Set the bit in the icon }
- fIconView.DrawBit(iconBit, fTurnBitsOn); { …and draw it in the edit view. }
- END;
-
- TrackMouse := SELF; { Return the same command object. }
- END;
-
-
-
-
- {-------------------------------------------------------------------------------------------}
- {-----------------------------------TIconBitMap methods-------------------------------------}
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.IIconBitMap;
-
- BEGIN
- fDataHandle := NewPermHandle(kIconSizeInBytes); { Allocate a handle for the bitmap. }
- FailNil(fDataHandle); { Fail if we can't allocate the handle. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.Free; OVERRIDE;
-
- BEGIN
- DisposIfHandle(fDataHandle); { dispose of icon data. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.SetIconBitMap(theBitMap : Handle);
-
- BEGIN
- BlockMove(theBitMap^, fDataHandle^, { …then copy it into the document's }
- kIconSizeInBytes) { …icon bitmap. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.Clear;
-
- VAR
- iconAsLongArray: LongArrayHdl;
- i: INTEGER;
-
- BEGIN
- iconAsLongArray := LongArrayHdl(fDataHandle); { Cast to array of longints. }
-
- FOR i := 0 TO kMaxLong DO { Clear the bits 32 at a time. }
- iconAsLongArray^^[i] := 0;
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.Invert;
-
- VAR
- iconAsLongArray: LongArrayHdl;
- i: INTEGER;
-
- BEGIN
- iconAsLongArray := LongArrayHdl(fDataHandle); { Cast to array of longints. }
-
- FOR i := 0 TO kMaxLong DO { Invert the bits 32 at a time. }
- iconAsLongArray^^[i] := BNOT(iconAsLongArray^^[i]);
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.IconBitToWordBit (iconBit: Point; VAR word, bit: INTEGER);
- { This converts the given icon bit to a word and bit in an array of long words. }
-
- VAR
- bitNumber: INTEGER;
-
- BEGIN
- bitNumber := iconBit.v * kIconVBits + iconBit.h;
- word := bitNumber DIV 32;
- bit := 31 - (bitNumber MOD 32);
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- FUNCTION TIconBitMap.GetBit (iconBit: Point): BOOLEAN;
- { Returns the state of the given bit in the icon being drawn. }
-
- VAR
- word: INTEGER;
- bitInWord: INTEGER;
-
- BEGIN
- IconBitToWordBit(iconBit, word, bitInWord);
-
- GetBit := BTst(LongArrayHdl(fDataHandle)^^[word], bitInWord);
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.SetBit (iconBit: Point; turnBitOn: BOOLEAN);
- { Set the state of the given bit in the icon being drawn. }
-
- VAR
- word: INTEGER;
- bitInWord: INTEGER;
-
- BEGIN
- IconBitToWordBit(iconBit, word, bitInWord);
-
- {$H-} { So the compiler thinks this is unsafe.}
- IF turnBitOn THEN
- BSet(LongArrayHdl(fDataHandle)^^[word], bitInWord)
- ELSE
- BClr(LongArrayHdl(fDataHandle)^^[word], bitInWord);
- {$H+}
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- FUNCTION TIconBitMap.Copy: TIconBitMap;
-
- VAR
- copyOfIcon: TIconBitMap;
-
- BEGIN
- New(copyOfIcon); { Create a TIcon object. }
- FailNIL(copyOfIcon); { Make sure we were successful. }
- copyOfIcon.IIconBitMap; { Initialize it. }
- copyOfIcon.SetIconBitMap(fDataHandle); { Copy the data. }
- Copy := copyOfIcon; { Return a reference to the new handle. }
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.Draw (area: Rect);
-
- BEGIN
- PlotIcon(area, fDataHandle);
- END;
-
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.CopyDataTo (anIcon: TIconBitMap);
-
- BEGIN
- anIcon.SetIconBitMap(fDataHandle); { Copy data to the new icon. }
- END;
-
-
- {-------------------------------------------------------------------------------------------}
-
- PROCEDURE TIconBitMap.Fields (PROCEDURE DoToField (fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TIconBitMap', NIL, bClass);
- DoToField('fDataHandle', @fDataHandle, bHandle);
-
- INHERITED Fields(DoToField);
- END;
-
-